/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2017 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.axelor.apps.bankpayment.service.bankorder.file.cfonb;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.axelor.apps.account.exception.IExceptionMessage;
import com.axelor.apps.tool.StringTool;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.IException;
import com.axelor.i18n.I18n;
import com.google.common.base.Strings;

public class CfonbToolService {


	/**
	 * Procédure permettant de vérifier que la chaine de caractère ne contient que des entier
	 * @param s
	 * 			La chaine de caractère à tester
	 * @param company
	 * 			Une société
	 * @throws AxelorException
	 */
	public void testDigital(String value, String zone) throws AxelorException  {
		if(!StringTool.isDigital(value))  {
					throw new AxelorException(String.format(I18n.get(IExceptionMessage.CFONB_TOOL_DIGITAL_ZONE_NOT_CORRECT),
							zone, value), IException.CONFIGURATION_ERROR);
		}
	}


	/**
	 * Procédure permettant de vérifier la longueur d'un enregistrement CFONB
	 * @param s
	 * 			Un enregistrement CFONB
	 * @param company
	 * 			Une société
	 * @param type
	 * 	 	Le type d'enregistrement :
	 * 		<ul>
     *      <li>0 = émetteur</li>
     *      <li>1 = destinataire</li>
     *      <li>2 = total</li>
     *      <li>3 = entête</li>
     *      <li>4 = détail</li>
     *      <li>5 = fin</li>
     *  	</ul>
	 *
	 * @param size
	 * 			La longueur de l'enregistrement
	 * @throws AxelorException
	 */
	public void testLength(String s, int size) throws AxelorException  {
		if(s.length() != size)  {
			throw new AxelorException(String.format(I18n.get(IExceptionMessage.CFONB_TOOL_NB_OF_CHAR_PER_LINE),
					size), IException.CONFIGURATION_ERROR);
		}
	}
	
	
	/**
	 * Méthode permettant de mettre en majuscule et sans accent un CFONB
	 * @param cFONB
	 * @return
	 * 		Le CFONB nettoyé
	 */
	public List<String> toUpperCase(List<String> cFONB)  {
		List<String> upperCase = new ArrayList<String>();
		for(String s : cFONB)  {
			upperCase.add(StringTool.deleteAccent(s.toUpperCase()));
		}
		return upperCase;
	}
	
	

	/**
	 * Méthode permettant de mettre en majuscule et sans accent un CFONB
	 * @param cFONB
	 * @return
	 * 		Le CFONB nettoyé
	 */
	public String toUpperCase(String record)  {

		return StringTool.deleteAccent(record.toUpperCase());
	
	}
	
	public void checkFilled(String value, String numZone) throws AxelorException  {
		
		if(Strings.isNullOrEmpty(value))  {
			throw new AxelorException(String.format(I18n.get(IExceptionMessage.CFONB_TOOL_EMPTY_ZONE), numZone), IException.CONFIGURATION_ERROR);
		}
		
		
	}
	
	
	public String normalizeNumber(BigDecimal amount)  {
		
		return amount.setScale(2).toString().replace(".","");
		
	}
	
	/**
	 * "M" = Obligatoire (Mandatory)
	 */
	public final String STATUS_MANDATORY = "M";
	/**
	 * "O" = Optionnel (Optional)
	 */
	public final String STATUS_OPTIONAL = "O";
	/**
	 * "D" = Dépendant (Dependent), la condition de présence de la donnée est précisée dans les tableaux de description des enregistrements
	 */
	public final String STATUS_DEPENDENT = "D";
	/**
	 * "N" = Non utilisée (zone que le CFONB se réserve le droit d'utiliser ultérieurement qui doit alors être à
	 * blanc, ou zone non utilisée pour ce type de remise qui est alors ignorée par la banque).
	 */
	public final String STATUS_NOT_USED = "N";

	/**
	 * "AN" = alphanumérique
	 */
	public final String FORMAT_ALPHA_NUMERIC = "AN";
	/**
	 * "N" = numérique
	 */
	public final String FORMAT_NUMERIC = "N";
	/**
	 * "A" = Alphabétique
	 */
	public final String FORMAT_ALPHA = "A";

	
	public String createZone(String numOfZone, String value, String status, String format, int length) throws AxelorException  {
		
		String zone = value;
		
		/** la colonne "Statut" correspond au statut des données et peut prendre les valeurs : **/
		switch (status) {
		
		case STATUS_MANDATORY :
			this.checkFilled(zone, numOfZone);
			
			break;
			
		case STATUS_OPTIONAL :
			
			if(zone == null)  {  zone = "";  }
			break;
			
		case STATUS_DEPENDENT:
			
			if(zone == null)  {  zone = "";  }
			break;
			
		case STATUS_NOT_USED:
			zone = "";
			break;

		default:
			break;
		}
		
		/** la colonne "Format" correspond au format des données et peut prendre les valeurs : **/
		switch (format) {
		
		case FORMAT_ALPHA_NUMERIC:
			zone = StringTool.deleteAccent(zone);
			zone = StringTool.fillStringRight(zone, ' ', length);
			break;

		case FORMAT_NUMERIC:
			this.testDigital(zone, numOfZone);
			zone = StringTool.fillStringLeft(zone, '0', length);
			break;

		case FORMAT_ALPHA:
			this.testDigital(zone, numOfZone);
			zone = StringTool.deleteAccent(zone);
			zone = StringTool.fillStringRight(zone, ' ', length);
			break;

		default:
			break;
		}
		
		return zone;
		
	}
	
	public String createZone(String numOfZone, int value, String status, String format, int length) throws AxelorException  {
		
		return this.createZone(numOfZone, Integer.toString(value), status, format, length);
		
	}
	
	public String createZone(String numOfZone, BigDecimal value, String status, String format, int length) throws AxelorException  {
		
		return this.createZone(numOfZone, this.normalizeNumber(value), status, format, length);
		
	}

	/**
	 * Fonction permettant de créer le CFONB
	 * @param senderCFONB
	 * 				Un enregistrement 'émetteur'
	 * @param recipientCFONB
	 * 				Un liste d'enregistrement 'destinataire'
	 * @param totalCFONB
	 * 				Un enregistrement 'total'
	 * @return
	 * 				Le CFONB
	 */
	public List<String> createCFONBFile(String senderRecord, List<String> recipientRecord, String totalRecord)  {
		// checker meme compte emetteur
		// checker meme type de virement
		// checker meme date de règlement

		List<String> cFONB = new ArrayList<String>();
		cFONB.add(senderRecord);
		cFONB.addAll(recipientRecord);
		cFONB.add(totalRecord);
		return cFONB;
	}

}
